import copy
import json
import logging
import time
from logging import handlers
import random

import allure

from conf import settings


class LogHandler(object):
    # 日志级别关系映射
    level_relations = {
        'debug': logging.DEBUG,
        'info': logging.INFO,
        'warning': logging.WARNING,
        'error': logging.ERROR,
        'crit': logging.CRITICAL
    }

    def __init__(self, filename, level='info', when='D'):
        self.logger = logging.getLogger(filename)

        self.log_colors_config = {
            'DEBUG': 'cyan',
            'INFO': 'green',
            'WARNING': 'yellow',
            'ERROR': 'red',
            'CRITICAL': 'red',
        }

        # 设置日志格式
        format_str = logging.Formatter(settings.LOG_FMT)
        # 设置日志级别
        self.logger.setLevel(self.level_relations.get(level))
        # 往屏幕上输出
        sh = logging.StreamHandler()
        # 设置屏幕上显示的格式
        sh.setFormatter(format_str)
        # 往文件里写入#指定间隔时间自动生成文件的处理器
        th = handlers.TimedRotatingFileHandler(
            filename=filename, when=when, backupCount=settings.BACK_COUNT, encoding='utf-8')
        """
        # 实例化TimedRotatingFileHandler
        # interval是时间间隔，
        # backupCount是备份文件的个数，如果超过这个个数，就会自动删除，
        # when是间隔的时间单位，单位有以下几种：
        # S 秒
        # M 分
        # H 小时、
        # D 天、
        # W 每星期（interval==0时代表星期一）
        # midnight 每天凌晨    
        """
        # 设置文件里写入的格式
        th.setFormatter(format_str)
        # 把对象加到logger里
        self.logger.addHandler(sh)
        self.logger.addHandler(th)


INFO = LogHandler(settings.INFO_LOG_PATH, level='info')
ERROR = LogHandler(settings.ERROR_LOG_PATH, level='error')


def log_process(func):
    def request(*args, **kwargs):
        start = time.time_ns()
        req = func(*args, **kwargs)
        end = time.time_ns()
        test_time = (end - start) // 1000000  # 测试时间

        res = copy.deepcopy(req.response)

        def log():
            with allure.step(f"测试耗时：{test_time} ms"):
                allure.attach(json.dumps(req.values(), indent=4, ensure_ascii=False), "请求体", allure.attachment_type.JSON)
                allure.attach(json.dumps(res, indent=4, ensure_ascii=False), "响应体", allure.attachment_type.JSON)

        if kwargs.get("is_depend"):
            with allure.step(f"依赖接口{req.story}.{req.title}测试"):
                log()
        else:
            with allure.step(f"接口{req.story}.{req.title}测试"):
                log()
        if test_time > 300:
            raise TimeoutError(f"本次请求时长超为{test_time}ms，超出 300ms")

        return req

    return request


if __name__ == '__main__':
    ERROR.logger.error("测试")
